using System;

namespace Tycho.Parser.Peg {
    class SpecialKeywordBuilder : ISpecialKeywordBuilder {
        private readonly ISpecialKeywordProductionFactory KeywordProductionFactory;

        public SpecialKeywordBuilder () : this (new SpecialKeywordProductionFactory ()) {}

        public SpecialKeywordBuilder (ISpecialKeywordProductionFactory keywordProductionFactory) {
            KeywordProductionFactory = keywordProductionFactory;
        }


        public IProduction Build (string keyword) {
            switch (keyword) {
                case "{":
                    return KeywordProductionFactory.CreateBeginBlock ();
                case "}":
                    return KeywordProductionFactory.CreateEndBlock ();
                case ";":
                    return KeywordProductionFactory.CreateStatementDelimiter ();
                case "(":
                    return KeywordProductionFactory.CreateIncrementingPunctuation (keyword);
                case "[":
                    return KeywordProductionFactory.CreateIncrementingPunctuation (keyword);
                case ")":
                    return KeywordProductionFactory.CreateDecrementingPunctuation (keyword);
                case "]":
                    return KeywordProductionFactory.CreateDecrementingPunctuation (keyword);
            }

            if (IsIdentifier (keyword)) {
                return KeywordProductionFactory.CreateIdentifierKeyword (keyword);
            } else if (IsOperator (keyword)) {
                return KeywordProductionFactory.CreateOperatorKeyword (keyword);
            }

            return KeywordProductionFactory.CreatePunctuation (keyword);
        }

        private static bool IsOperator (string keyword) {
            var op = OperatorProduction.CreateTerminal ();
            return CanParseWholeString (op, keyword);
        }

        private static bool CanParseWholeString (IProduction op, string keyword) {
            var opResult = op.Parse (keyword);
            return opResult != null && opResult.Index == keyword.Length;
        }

        private static bool IsIdentifier (string keyword) {
            var id = IdentifierProduction.CreateTerminal ();
            return CanParseWholeString (id, keyword);
        }
    }
}